package com.quality.web.controller.business;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.IService;
import com.quality.business.domain.*;
import com.quality.business.domain.resp.QualityResultsResp;
import com.quality.business.domain.resp.QualityResultsValue;
import com.quality.business.domain.resp.RuleResult;
import com.quality.business.service.*;
import com.quality.common.annotation.Log;
import com.quality.common.core.controller.BaseController;
import com.quality.common.core.domain.AjaxResult;
import com.quality.common.enums.BusinessType;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.devtools.tunnel.client.TunnelClient;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.xml.crypto.Data;
import java.util.*;


@PreAuthorize("@ss.hasAnyRoles('common,admin,common_admin')")
@RestController
@RequestMapping("/quality/result")
public class QualityResultsController extends BaseController {

    @Autowired
    private QualityRuleService ruleService;
    @Autowired
    private BodyTextDataService bodyTextDataService;
    @Autowired
    private DictJobService dictJobService;
    @Autowired
    private WeatherDataService weatherDataService;
    @Autowired
    private QualityStatisticsService statisticsService;

    @Log(title = "质检结果分析", businessType = BusinessType.INSERT)
    @GetMapping()
    public AjaxResult result(Integer groupId){
        Long QualitygGroupId = getQualitygGroupId();
        List<QualityStatistics> statistics = statisticsService.lambdaQuery().eq(QualityStatistics::getQualitygGroupId, QualitygGroupId).orderByDesc(QualityStatistics::getNum).list();
        int num = 1;
        if (CollectionUtil.isNotEmpty(statistics)){
            num = statistics.get(0).getNum() + 1;
        }
        errIf(ObjectUtil.isNull(groupId),"请选择分组");
//        质检总数初始化
        List<QualityRule> rules = ruleService.lambdaQuery().eq(QualityRule::getGroupId, groupId).eq(QualityRule::getIsEnable,true).list();
        List<QualityResultsResp> resps = new ArrayList<>();
        List<QualityResultsValue> totalValues = new ArrayList<>();
        QualityResultsValue totalValue1 = new QualityResultsValue().setName("合格").setValue(0);
        QualityResultsValue totalValue2 = new QualityResultsValue().setName("不合格").setValue(0);
        totalValues.add(totalValue1);
        totalValues.add(totalValue2);
        resps.add(new QualityResultsResp().setTitle("质检总数").setValues(totalValues));
//        违反规则情况初始化
        List<QualityResultsValue> valuess = new ArrayList<>();
        QualityResultsValue valueOne = new QualityResultsValue().setName("违反一条规则").setValue(0);
        QualityResultsValue valueTwo = new QualityResultsValue().setName("违反两条规则").setValue(0);
        QualityResultsValue value3 = new QualityResultsValue().setName("违反三条及以上规则").setValue(0);
        QualityResultsValue value4 = new QualityResultsValue().setName("没有违反规则").setValue(0);
        valuess.add(valueOne);
        valuess.add(valueTwo);
        valuess.add(value3);
        valuess.add(value4);
        resps.add(new QualityResultsResp().setTitle("违反规则情况").setValues(valuess));


        Map<String,Integer> map = new HashMap<>();
        if (CollectionUtil.isNotEmpty(rules)){
            for (QualityRule rule : rules) {
//              单条规则初始化
                List<QualityResultsValue> values = new ArrayList<>();
                QualityResultsValue value1 = new QualityResultsValue().setName("合格").setValue(0);
                QualityResultsValue value2 = new QualityResultsValue().setName("不合格").setValue(0);
                values.add(value1);
                values.add(value2);
                resps.add(new QualityResultsResp().setTitle(rule.getDescription()).setValues(values));
                Integer integer = map.get(rule.getField());
                if (ObjectUtil.isNull(integer)){
                    integer = 0;
                }
                boolean flag = true;
//                规则是否启用
                if (rule.getIsEnable()){
                    if ("body_text_data".equals(rule.getTable())){
                        List<BodyTextData> list = bodyTextDataService.list();

                        if (CollectionUtil.isNotEmpty(list)){
                            for (BodyTextData data : list) {
                                boolean check = check(data, rule);
//                              正确数据返回false,成功值加1
                                if (check){
                                    value2.setValue(value2.getValue()+1);
                                    totalValue2.setValue(totalValue2.getValue()+1);
                                    if (flag){
//                                      字段有错误数据，对其违反规则数加一
                                        integer++;
                                        flag = !flag;
                                    }
                                }else {
                                    value1.setValue(value1.getValue()+1);
                                    totalValue1.setValue(totalValue1.getValue()+1);
                                }
//                              键值对匹配字段，违反多条规则
                                map.put(rule.getField(),integer);

                            }
                        }
                    }else if ("dict_job".equals(rule.getTable())){
                        List<DictJob> list = dictJobService.list();
                        if (CollectionUtil.isNotEmpty(list)){
                            for (DictJob job : list) {

                                boolean check = check(job,rule);

                                if (check){
                                    value2.setValue(value2.getValue()+1);
                                    totalValue2.setValue(totalValue2.getValue()+1);
                                    if (flag){
                                        integer++;
                                        flag = !flag;
                                    }
                                }else {
                                    value1.setValue(value1.getValue()+1);
                                    totalValue1.setValue(totalValue1.getValue()+1);
                                }
                                map.put(rule.getField(),integer);

                            }
                        }
                    }else {
                        List<WeatherData> list = weatherDataService.list();
                        if (CollectionUtil.isNotEmpty(list)){
                            for (WeatherData weatherData : list) {

                                boolean check = check(weatherData,rule);
                                if (check){
                                    value2.setValue(value2.getValue()+1);
                                    totalValue2.setValue(totalValue2.getValue()+1);
                                    if (flag){
                                        integer++;
                                        flag = !flag;
                                    }
                                }else {
                                    value1.setValue(value1.getValue()+1);
                                    totalValue1.setValue(totalValue1.getValue()+1);
                                }
                                map.put(rule.getField(),integer);
                            }
                        }
                    }
                }
//                同步质检统计数据
                QualityStatistics one = statisticsService.lambdaQuery().eq(QualityStatistics::getQualitygGroupId, QualitygGroupId).eq(QualityStatistics::getRuleId, rule.getId()).one();
                if (ObjectUtil.isNull(one)) {
                    statisticsService.save(new QualityStatistics()
                            .setRuleId(rule.getId())
                            .setQualitygGroupId(rule.getQualitygGroupId())
                            .setQualified(value1.getValue())
                            .setFailed(value2.getValue())
                            .setNum(num));
                    num++;
                }else {
                        one.setQualified(value1.getValue()).setFailed(value2.getValue());
                        statisticsService.updateById(one);
                }
            }
        }
//        针对map值，进行统计
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            Integer value = entry.getValue();
            if (value == 0){
                value4.setValue(value4.getValue()+1);
            }
            if (value==1){
                valueOne.setValue(valueOne.getValue()+1);
            }
            if (value==2){
                valueTwo.setValue(valueTwo.getValue()+1);
            }
            if (value>=3){
                value3.setValue(value3.getValue()+1);
            }
        }

        return AjaxResult.success(resps);
    }

    public boolean check(TableFieldAbstract o,QualityRule rule){
        if (ObjectUtil.isNull(o)){
            return true;
        }
        Object value = o.getValue(rule.getField());
        try {
            switch (rule.getRule()){
//                非空检查
                case 1:
                    if (StrUtil.isNotEmpty(value.toString()) || ObjectUtil.isNotNull(value)){
                        return false;
                    }

//                 范围检查
                case 2:
                    Double begin = Double.parseDouble(rule.getBegin());
                    Double end = Double.parseDouble(rule.getEnd());
                    Double i = Double.parseDouble(value+"");
                    if (ObjectUtil.isNotNull(value) && begin <= i && end >= i ){
                        return false;
                    }
//                    时间范围

                case 3:
                    Long beginTime = Long.parseLong(rule.getBegin());
                    Long endTime = Long.parseLong(rule.getEnd());
                    long time = DateUtil.date((Date) value).getTime();
                    if (ObjectUtil.isNotNull(value) && beginTime <= time && endTime >= time ){
                        return false;
                    }
//                    正则表达式
                case 4:
                    String s = value+"";
                    boolean matches = s.matches(rule.getPatten());
                    if (matches){
                        return false;
                    }
                default:
                    return true;
            }
        } catch (Exception e) {
        }
        return true;
    }
}
